package com.william.git;

import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.william.git.model.GitCommitLog;

/**
 * Git日志操作工具类
 * 
 * @author wuyong
 * @date 2025/1/21
 */
public class GitLog {
    
    /**
     * 获取指定时间范围内的git提交日志
     *
     * @param repoUrl git远程仓库地址
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @param username git用户名
     * @param password git密码
     * @return 提交日志列表
     */
    public List<GitCommitLog> getGitLogs(String repoUrl, Date startDate, Date endDate, String username, String password) {
        List<GitCommitLog> commitLogs = new ArrayList<>();
        File tempDir = null;
        
        try {
            // 创建临时目录
            tempDir = File.createTempFile("git_", "_temp");
            if (!tempDir.delete() || !tempDir.mkdir()) {
                throw new IOException("无法创建临时目录");
            }
            
            // 克隆远程仓库（添加认证信息）
            CloneCommand cloneCommand = Git.cloneRepository()
                    .setURI(repoUrl)
                    .setDirectory(tempDir);
            
            // 如果提供了用户名和密码，则设置认证信息
            if (username != null && !username.isEmpty() && password != null) {
                cloneCommand.setCredentialsProvider(
                    new UsernamePasswordCredentialsProvider(username, password)
                );
            }
            
            Git git = cloneCommand.call();
            
            try (git) {
                Iterable<RevCommit> commits = git.log().all().call();
                
                for (RevCommit commit : commits) {
                    Date commitDate = new Date(commit.getCommitTime() * 1000L);
                    
                    if (commitDate.after(startDate) && commitDate.before(endDate)) {
                        GitCommitLog log = new GitCommitLog(
                            commit.getName(),
                            commit.getAuthorIdent().getName(),
                            commitDate,
                            commit.getFullMessage()
                        );
                        commitLogs.add(log);
                    }
                }
            }
        } catch (IOException | GitAPIException e) {
            e.printStackTrace();
        } finally {
            // 清理临时目录
            if (tempDir != null && tempDir.exists()) {
                deleteDirectory(tempDir);
            }
        }
        
        return commitLogs;
    }
    
    /**
     * 递归删除目录
     *
     * @param directory 要删除的目录
     */
    private void deleteDirectory(File directory) {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteDirectory(file);
                } else {
                    file.delete();
                }
            }
        }
        directory.delete();
    }

    /**
     * 获取本地仓库指定时间范围内的git提交日志
     *
     * @param localPath git本地仓库路径
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @return 提交日志列表
     * @throws IOException 当仓库路径无效或无法访问时抛出
     * @throws GitAPIException 当Git操作失败时抛出
     */
    public List<GitCommitLog> getLocalGitLogs(String localPath, Date startDate, Date endDate) throws IOException, GitAPIException {
        List<GitCommitLog> commitLogs = new ArrayList<>();
        
        // 打开本地仓库
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        try (Repository repository = builder.setGitDir(new File(localPath + "/.git"))
                .readEnvironment()
                .findGitDir()
                .build()) {
            
            try (Git git = new Git(repository)) {
                // 获取所有提交记录
                Iterable<RevCommit> commits = git.log().all().call();
                
                for (RevCommit commit : commits) {
                    Date commitDate = new Date(commit.getCommitTime() * 1000L);
                    
                    if (commitDate.after(startDate) && commitDate.before(endDate)) {
                        GitCommitLog log = new GitCommitLog(
                            commit.getName(),
                            commit.getAuthorIdent().getName(),
                            commitDate,
                            commit.getFullMessage()
                        );
                        commitLogs.add(log);
                    }
                }
            }
        }
        
        return commitLogs;
    }
} 